home *** CD-ROM | disk | FTP | other *** search
/ Aminet 2 / Aminet AMIGA CDROM (1994)(Walnut Creek)[Feb 1994][W.O. 44790-1].iso / Aminet / util / misc / Fudgit233.lha / Source / src / lexi.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-14  |  8.2 KB  |  345 lines

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <ctype.h>
  4.  
  5. #include "symbol.h"
  6. #include "code.h"
  7. #include "math.tab.h"
  8. #include "fudgit.h"
  9. #include "head.h"
  10.  
  11. #define LQUOTE '"'
  12. #define ANY (-1)
  13. extern int Ft_Samples;
  14. extern int Ft_Debug;
  15.  
  16. char Ft_Puffer[MAXMACRO+8];
  17.  
  18. static char *Pp;
  19. static int follow(char expect, int ifyes, int ifno);
  20.  
  21.  
  22. extern int Ft_autosymremove (int level);
  23. extern void Ft_matherror (char *s1, char *s2, int lino);
  24. extern int Ft_mathyyparse (void);
  25. int Ft_varcpy (char *to, char *from);
  26. extern int Ft_iolevel (void);
  27. extern int Ft_almost (register char *str1, register char *str2);
  28.  
  29. void Ft_initmathyylex(char *str)
  30. {
  31.     strcpy(Ft_Puffer, str);
  32.     Pp = Ft_Puffer;
  33.     if (Ft_Debug & DEBUG_MATH)
  34.         fputs(Pp, stderr);
  35. }
  36.  
  37. int Ft_mathyyerror(char *str)
  38. {
  39.     extern int Ft_mathyystate;
  40.     extern int Ft_mathyychar;
  41.  
  42.     Ft_autosymremove(0);
  43. #ifdef YYDEBUG
  44.     fprintf(stderr, "Cmode parser: %s. (token `%c`; current state %d)\n",
  45.     str, Ft_mathyychar, Ft_mathyystate);
  46.     Ft_catcher(ERRR);
  47. #else
  48.     Ft_matherror("Cmode parser: %s.", str, 0);
  49. #endif
  50.     return(ERRR);  /* DUMMY */
  51. }
  52.  
  53. int Ft_mathyylex(void)
  54. {
  55.     int c;
  56.     extern int Ft_iolevel(void);
  57.     extern int Ft_Inproto, Ft_Indef, Ft_Inauto, Ft_Inbrace;
  58.  
  59.     while (*Pp == ' ' || *Pp == '\t')  /* remove space if any */
  60.         Pp++;
  61.     if (*Pp == 0)
  62.         return(0);
  63.     c = *Pp;
  64.     if (c == '.' || isdigit(c)) {  /* a number  */
  65.         double d;
  66.         if (sscanf(Pp, "%lf", &d) != 1) {
  67.             Ft_matherror("Wierd number near... %s", Pp, 0);
  68.         }
  69.         while (c == '.' || isdigit(c))
  70.             c = *++Pp;
  71.         if (c == 'e' || c == 'E') {
  72.             c = *++Pp;
  73.             if (c == '-')
  74.                 c = *++Pp;
  75.             while (isdigit(c))
  76.                 c = *++Pp;
  77.         }
  78.         Ft_mathyylval.val = d;
  79.         return(NUMBER);
  80.     }
  81.     else if (c == LQUOTE) { /* a string */
  82.         char strbuf[TOKENSIZE+1];
  83.         char *p;
  84.  
  85.         c = *++Pp;
  86.         p = strbuf;
  87.         while (c != LQUOTE) {
  88.             if (c == '\n' || c == '\0') {
  89.                 fprintf(stderr, "Math error: Unmatched quote %c.\n", LQUOTE);
  90.                 Ft_catcher(ERRR);
  91.             }
  92.             if ((p - strbuf) >= TOKENSIZE) {
  93.                 *p = '\0';
  94.                 Ft_matherror("%s: String too long.", strbuf, 0);
  95.             }
  96.             if (c == '\\') {
  97. #ifdef NOALERTCHAR
  98.                 static char transtab[] = "b\bf\fn\nr\rt\tv\v";
  99. #else
  100.                 static char transtab[] = "b\bf\fn\nr\rt\ta\av\v";
  101. #endif
  102.                 char *ch;
  103.                 extern char *strchr(const char *, int);
  104.  
  105.                 c = *++Pp;
  106.                 if (islower(c) && (ch = strchr(transtab, c))) {
  107.                     *p++ = ch[1];
  108.                 }
  109.                 else {  /* put next char as is */
  110.                     *p++ = c;
  111.                 }
  112.                 c = *++Pp;
  113.                 continue;
  114.             }
  115.             *p++ = c;
  116.             c = *++Pp;
  117.         }
  118.         *p = '\0';
  119.         Pp++; /* swallow last quote */
  120.         Ft_mathyylval.sym = Ft_install("", STRING, strlen(strbuf));
  121.         strcpy(Ft_mathyylval.sym->u.str, strbuf);
  122.         return(STRING);
  123.     }
  124.     else if (isalpha(c)) {   /* a function or a variable  */
  125.         char vname[TOKENSIZE+1];
  126.         Symbol *s;
  127.         int type, argno;
  128.  
  129.         type = Ft_varcpy(vname, Pp);
  130.         Pp += strlen(vname);
  131.         if (Ft_Inproto) {
  132.             if (Ft_autolookup(vname, ANY))
  133.                 Ft_matherror("%s: Repeated argument name.", vname, 0);
  134.             switch (type) {
  135.             case VAR:
  136.                 Ft_autoinstall(vname, ARG, 0);
  137.                 return(VARARG);
  138.             case STRVAR:
  139.                 Ft_autoinstall(vname, ARG, 0);
  140.                 return(STRVARARG);
  141.             case VEC:
  142.                 Ft_autoinstall(vname, ARG, 0);
  143.                 if (Ft_almost(vname, "P!ARAM"))
  144.                     return(PARARG);
  145.                 return(VECARG);
  146.             default:
  147.                 Ft_matherror("%s: Impossible case in lexi!", vname, 0);
  148.             }
  149.         }
  150.         if (Ft_Inauto) {
  151.             if (Ft_Indef && Ft_autolookup(vname, 0))
  152.                 Ft_matherror("%s: Already defined as a prototype.", vname, 0);
  153.             switch (type) {
  154.             case VAR:
  155.                 Ft_autoinstall(vname, AUTO, Ft_Inbrace);
  156.                 return(VARARG);
  157.             case STRVAR:
  158.                 Ft_autoinstall(vname, AUTO, Ft_Inbrace);
  159.                 return(STRVARARG);
  160.             case VEC:
  161.                 Ft_autoinstall(vname, AUTO, Ft_Inbrace);
  162.                 return(VECARG);
  163.             default:
  164.                 Ft_matherror("%s: Impossible case in lexi!", vname, 0);
  165.             }
  166.         }
  167.         if ((argno = Ft_autolookup(vname, ANY))) {
  168.             Ft_mathyylval.narg = argno;
  169.             switch (type) {
  170.             case STRVAR: return(STRVARARG);
  171.             case VAR: return(VARARG);
  172.             case VEC: if (Ft_almost(vname, "P!ARAM"))
  173.                         return(PARARG);
  174.                     return(VECARG);
  175.             default:
  176.                 Ft_matherror("%s: Impossible case in lexi!", vname, 0);
  177.             }
  178.         }
  179.         if ((s = Ft_lookup(vname)) == 0) {
  180.             switch (type) {
  181.             case STRVAR:
  182.                 s = Ft_install(vname, UNDEFSTRVAR, 0);
  183.                 break;
  184.             case VAR:
  185.                 s = Ft_install(vname, UNDEFVAR, 1);
  186.                 break;
  187.             case VEC:
  188.                 s = Ft_install(vname, UNDEFVEC, Ft_Samples);
  189.                 break;
  190.             default:
  191.                 Ft_matherror("%s: Impossible case in lexi!", vname, 0);
  192.             }
  193.         }
  194.         Ft_mathyylval.sym = s;
  195.         switch(s->type) {
  196.             case UNDEFVAR: return(VAR);
  197.             case UNDEFVEC: return(VEC);
  198.             case UNDEFSTRVAR: return(STRVAR);
  199.             case BLTINVAR: return(VAR);
  200.             case BLTINSTRVAR: return(STRVAR);
  201.             case BLTINCONST: return(CONST);
  202.             case BLTINSTRCONST: return(STRCONST);
  203.             default: return(s->type);
  204.         }
  205.     }
  206.     Pp++;
  207.     switch (c) {
  208.     case '+':
  209.         if(follow('+', INCR, '+') == '+')
  210.             return(follow('=', ADDASS, '+'));
  211.         else
  212.             return(INCR);
  213.     case '-':
  214.         if(follow('-', DECR, '-') == '-')
  215.             return(follow('=', SUBASS, '-'));
  216.         else
  217.             return(DECR);
  218.     case '/':    return(follow('=', DIVASS, '/'));
  219.     case '*':    return(follow('=', MULASS, '*'));
  220.     case '>':    return(follow('=', GE, GT));
  221.     case '<':    return(follow('=', LE, LT));
  222.     case '=':    return(follow('=', EQ, '='));
  223.     case '!':    return(follow('=', NE, NOT));
  224.     case '|':    return(follow('|', OR, '|'));
  225.     case '&':    return(follow('&', AND, '&'));
  226.     default:     return(c);
  227.     }
  228. }
  229.  
  230. static int follow(char expect, int ifyes, int ifno)
  231. {
  232.     if (*Pp == expect) {
  233.        Pp++;
  234.        return(ifyes);
  235.     }
  236.     return(ifno);
  237. }
  238.  
  239. int Ft_more_input(int level, char *iprompt)
  240. {
  241.     int eof;
  242.     char *cp;
  243.     char prompt[128];
  244.     char *cpt;
  245.     extern char *Ft_expandedline(char *prompt, int type, int *eof);
  246.     extern char Ft_Prompt_cm[];
  247.     extern int Ft_Interact;
  248.  
  249.     cpt = prompt;
  250.     if (Ft_Interact && !Ft_iolevel()) {  /* Do we build a prompt ? */
  251.         int i = level;
  252.  
  253.         if (level>0) {
  254.             cp = cpt;
  255.             while (i) {
  256.                 *cp = '{';
  257.                 cp++; i--;
  258.             }
  259.             if (iprompt) {
  260.                 int len = strlen(iprompt);
  261.  
  262.                 strcpy(cp, iprompt);
  263.                 cp += len;
  264.             }
  265.             strcpy(cp, "...    ");
  266.             cp += 7;
  267.             for (i=level;i;i--,cp+=4)
  268.                 strcpy(cp, "    ");
  269.         }
  270.         else if (iprompt) {
  271.             cpt = iprompt;
  272.         }
  273.         else {
  274.             cpt = Ft_Prompt_cm;
  275.         }
  276.     }
  277.     else {
  278.         *prompt = '\0';
  279.     }
  280.     if ((cp = Ft_expandedline(cpt, EXPANSION | PARENTH, &eof)) == NULL) {
  281.         if (eof) {
  282.             if (eof > 0)    /* not a ^D */
  283.             fputs("Warning: Eof or Eom occurred while still in cmode.\n",
  284.             stderr);
  285.             return(0);
  286.         }
  287.         Ft_initmathyylex("\n");  /* forgive newlines in statements */
  288.         return(ERRR);  /* this means to continue */
  289.     }
  290.     if (Ft_almost(cp, "fm!ode") || Ft_almost(cp, "quit")) {
  291.         return(0);
  292.     }
  293.     else if (Ft_almost(cp, "cm!ode")) {
  294.         fputs("Warning: cmode: Program already in C mode: Line ignored.\n",
  295.         stderr);
  296.         return(ERRR); /* We want to continue */
  297.     }
  298.     Ft_initmathyylex(cp);
  299.     return(1);
  300. }
  301.  
  302. #define isacceptable(c)  ((c) == '_')
  303.  
  304. int Ft_varcpy(char *to, char *from)
  305. {
  306.     int up = 0;
  307.     int alf = 0;
  308.     int c = *from;
  309.     int i = 0;
  310.     char *save = to;
  311.  
  312.     if (!to)
  313.         to = from;
  314.     do {  /* copy variable name  */
  315.         if (!isdigit(c) && !isacceptable(c)) {
  316.             up += (isupper(c) != 0);
  317.             alf++;
  318.         }
  319.         *to++ = *from;
  320.         c = *++from;
  321.         if (++i >= TOKENSIZE) {
  322.             *to = '\0';
  323.             Ft_matherror("%s: Variable name too long!", save, 0);
  324.         }
  325.     } while (c && (isalnum(c) || isacceptable(c)));
  326.     *to = '\0';
  327.     if (up != 0 && up != alf) /* not all lower-upper case */
  328.         return(STRVAR);
  329.     if (up == 0)   /* All lower case  => variable or function */
  330.         return(VAR);
  331.     return(VEC);
  332. }
  333.  
  334. void Ft_mathuser(void)  /* mostly non-linear */
  335. {
  336.     extern char Ft_UFunction[];
  337.  
  338.     Ft_initcode();
  339.     Ft_initmathyylex(Ft_UFunction);
  340.     for (;*Pp;Ft_initcode())
  341.         Ft_mathyyparse();
  342.  
  343.     return;
  344. }
  345.